package com.yxy.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.core.JdbcTemplate;


import javax.sql.DataSource;

/**
 * @ClassDescription:java的配置类，替代xml配置文件
 * 1、包扫描注解配置
 * @ComponentScan({"com.yxy.ioc_01", "com.yxy.ioc_02"})
 * 2、引用外部的配置文件  @PropertySource("classpath:jdbc:properties")
 * 3、声明第三方依赖的bean组件
 *   步骤1：添加@Configuration  代表我们是配置类
 *   步骤2；实现上面的三个功能注解
 * @JdkVersion: 17
 * @Author: yxy
 * @Created: 2023/10/30 8:16
 */

@ComponentScan({"com.yxy.ioc_01"})
@PropertySource("classpath:jdbc.properties")
@Configuration
public class JavaConfiguration {
    @Value("${class04.url}")
    private String url;
    @Value("${class04.driver}")
    private String driver;
    @Value("${class04.username}")
    private String username;
    @Value("${class04.password}")
    private String password;


    /*
    * <bean id="" class ="" 一个方法
    * 方法的返回值类型 == bean组件的类型或者他的接口和父类
    * 方法名字   = bean id
    *
    *
    *
    *
    * 方法体可以自定义实现过程即可
    * 最重要一步：@Bean会真正让配置类的方法创建的组件存储到ioc容器！！！
    *
    * 问题1：beanName问题
    * 默认：方法名
    * 指定：name  / value 属性  起名字，覆盖方法名
    *
    * 问题2：
    * 周期方法如何指定
    * 原有注解方法：
    * @PostConstruct  初始化使用注解  + @ PreDestroy销毁方法使用的注解
    * bean属性指定initMethod/destroyMethod指定
    * 问题3：作用域
    * 和以前一样@Scope注解，默认是单例
    *
    * 问题4：
    * 如何引用其他的ioc组件
    * 情况一：直接调用对方的bean方法即可
    * 情况二：直接形参变量进行引入，要求必须有对应的组件，如果有多个，形参名 = 组件id标识即可
    *
    *
    *
    * */

    @Bean(name = "ergouzi")
    public DruidDataSource dataSource1() {
//        实现具体的实例化过程
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setDriverClassName(driver);
        dataSource.setUsername(username);
        dataSource.setUrl(password);
        return dataSource;
    }

    @Bean("lvdandan")
//    @Scope(scopeName = ConfigurableBeanFactory.SCOPE_SINGLETON)
    public DruidDataSource dataSource2() {
//        实现具体的实例化过程
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setDriverClassName(driver);
        dataSource.setUsername(username);
        dataSource.setUrl(password);
        return dataSource;
    }

    //    JdbcTemplate  -> DruidDataSource
    @Bean
    public JdbcTemplate jdbcTemplate() {
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
//        需要DataSource  需要ioc容器的其他组件
//        方案一：如果其他组件也是@Bean方法，可以直接调用  |  从ioc容器获取组件
        jdbcTemplate.setDataSource(dataSource1());
        return jdbcTemplate;
    }

    @Bean
    public JdbcTemplate jdbcTemplate1(DataSource lvdandan, DataSource ergouzi) {
        //  需要DataSource 需要ioc容器的其他组件
//        方案二：形参列表声明想要的组件类型，可以是一个也可以是多个！ioc容器也会注入
//        如果没有：形参变量注入，要求必须有对应类型的组件，如果没有抛出异常！
//        如果有多个：可以使用形参名称等同于对应的beanid标识即可
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(lvdandan);
        return jdbcTemplate;
    }

}
